package com.xinqi.modules.prepare.folder.controller.web;

import com.xinqi.common.base.dto.CommonFileDTO;
import com.xinqi.common.base.error.CommonErrors;
import com.xinqi.common.base.response.PageInfo;
import com.xinqi.common.base.response.R;
import com.xinqi.common.base.utils.lambda.Lambdas;
import com.xinqi.modules.prepare.folder.domain.PrepareFileFolderEntity;
import com.xinqi.modules.prepare.folder.dto.req.PrepareFileFolderCopyDTO;
import com.xinqi.modules.prepare.folder.dto.req.PrepareFileFolderCreateDTO;
import com.xinqi.modules.prepare.folder.dto.req.PrepareFileFolderMoveDTO;
import com.xinqi.modules.prepare.folder.dto.req.PrepareFileFolderQueryDTO;
import com.xinqi.modules.prepare.folder.dto.req.PrepareFileFolderUpdateDTO;
import com.xinqi.modules.prepare.folder.dto.req.PrepareFileShareURLDto;
import com.xinqi.modules.prepare.folder.dto.rsp.PrepareFileFolderResultDTO;
import com.xinqi.modules.prepare.folder.manager.PrepareFileFolderManager;
import com.xinqi.modules.prepare.folder.service.PrepareFileFolderService;
import com.xinqi.modules.prepare.prepare.enums.PrepareFileTypeEnum;
import com.xinqi.modules.prepare.prepare.enums.PrepareTypeEnum;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * 备课区文件夹WEB控制层
 *
 * @author: system
 * @date: 2023/03/19
 */
@Tag(name = "Web-备课区-文件/文件夹", description = "备课区-文件/文件夹Web接口")
@RestController
@RequestMapping("/web/prepare")
@RequiredArgsConstructor
public class PrepareFileFolderWebController {
    private final PrepareFileFolderService prepareFileFolderService;
    private final PrepareFileFolderManager prepareFileFolderManager;

    /**
     * 备课区文件夹-分页
     */
    @Operation(summary = "备课区文件夹-分页")
    @GetMapping("/{prepare-id}/file-folder/page")
    public R<PageInfo<PrepareFileFolderResultDTO>> page(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                                        @ParameterObject PrepareFileFolderQueryDTO dto) {
        dto.setPrepareId(prepareId);
        PageInfo<PrepareFileFolderResultDTO> page = prepareFileFolderService.page(dto, dto);
        return R.data(page);
    }

    /**
     * 备课区文件夹/文件-列表
     */
    @Operation(summary = "备课区文件夹/文件-列表")
    @GetMapping("/{prepare-id}/file-folder/list")
    public R<List<PrepareFileFolderResultDTO>> treeList(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                                        @ParameterObject PrepareFileFolderQueryDTO dto) {
        dto.setPrepareId(prepareId);
        List<PrepareFileFolderResultDTO> page = prepareFileFolderService.tree(dto);
        return R.data(page);
    }

    /**
     * 只能查询文件夹
     */
    @Operation(summary = "只能查询备课区下的文件夹")
    @GetMapping("/{prepare-id}/only-folder/page")
    public R<PageInfo<PrepareFileFolderResultDTO>> folderPage(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                                              @ParameterObject PrepareFileFolderQueryDTO dto) {
        dto.setPrepareId(prepareId);
        dto.setFileType(PrepareFileTypeEnum.FOLDER);
        PageInfo<PrepareFileFolderResultDTO> page = prepareFileFolderService.page(dto, dto);
        return R.data(page);
    }

    /**
     * 只能查询文件夹
     */
    @Operation(summary = "只能查询备课区下的文件夹(树)")
    @GetMapping("/{prepare-id}/only-folder/tree")
    public R<List<PrepareFileFolderResultDTO>> folderTree(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                                          @ParameterObject PrepareFileFolderQueryDTO dto) {
        CommonErrors.BAD_REQUEST.check(dto.getPrepareType() != null, "备课区类型不能为空");
        dto.setPrepareId(prepareId);
        dto.setFileType(PrepareFileTypeEnum.FOLDER);
        return R.data(prepareFileFolderService.tree(dto));
    }

    /**
     * 备课区文件夹-详情
     */
    @Operation(summary = "备课区文件夹-详情")
    @GetMapping("/{prepare-id}/file-folder/{id}")
    public R<PrepareFileFolderResultDTO> findById(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                                  @Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id) {
        PrepareFileFolderResultDTO dto = prepareFileFolderService.findById(id);
        return R.data(dto);
    }

    /**
     * 备课区文件/文件夹名称是否已存在
     */
    @Operation(summary = "备课区文件/文件夹名称是否已存在")
    @GetMapping("/{prepare-id}/file-folder/is-exist-name")
    public R<Boolean> isExistName(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                  @Parameter(description = "备课区类型", example = "1") PrepareTypeEnum type,
                                  @Parameter(description = "文件类型，FOLDER:文件夹；FILE:文件；", example = "FILE") PrepareFileTypeEnum fileType,
                                  @Parameter(description = "备课区文件名称", example = "快速提高") String name,
                                  @Parameter(description = "备课区父文件夹ID，根目录可以不填", example = "100001") Long pid,
                                  @Parameter(description = "当前修改的ID，新增不用填", example = "100001") Long oldId
    ) {
        pid = pid != null ? pid : 0;
        if (pid != 0) {
            PrepareFileFolderEntity entity = Lambdas.ofNull(prepareFileFolderManager.findById(pid), "父文件夹不存在");
            prepareId = entity.getPrepareId();
            type = entity.getType();
        }
        return R.data(prepareFileFolderService.isExistName(prepareId, type, name, pid, fileType, oldId));
    }

    /**
     * 新增备课区文件夹
     */
    @Operation(summary = "新增备课区文件夹")
    @PostMapping("/{prepare-id}/file-folder")
    public R<Long> insert(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                          @RequestBody PrepareFileFolderCreateDTO dto) {
        dto.setPrepareId(prepareId);
        return R.data(prepareFileFolderService.insert(dto));
    }

    /**
     * 修改备课区文件夹名称
     */
    @Operation(summary = "修改备课区文件夹名称(只能修改文件夹名称)")
    @PutMapping("/{prepare-id}/file-folder/{id}")
    public R<Boolean> update(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                             @Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id,
                             @RequestBody PrepareFileFolderUpdateDTO dto) {
        dto.setId(id);
        return R.data(prepareFileFolderService.updateFolderById(dto));
    }

    /**
     * 文件移动到
     */
    @Operation(summary = "移动到")
    @PutMapping("/{prepare-id}/file-folder/{id}/move")
    public R<Boolean> move(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                           @Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id,
                           @RequestBody PrepareFileFolderMoveDTO dto) {
        dto.setId(id);
        return R.data(prepareFileFolderService.move(dto));
    }

    /**
     * 文件批量移动到
     */
    @Operation(summary = "批量移动到")
    @PutMapping("/{prepare-id}/file-folder/batch-move")
    public R<Boolean> batchMove(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                @RequestBody List<PrepareFileFolderMoveDTO> dto) {
        return R.data(prepareFileFolderService.batchMove(dto));
    }

    /**
     * 文件复制到
     */
    @Operation(summary = "复制到")
    @PutMapping("/{prepare-id}/file-folder/{id}/copy")
    public R<Boolean> copy(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                           @Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id,
                           @RequestBody PrepareFileFolderCopyDTO dto) {
        dto.setId(id);
        return R.data(prepareFileFolderService.copy(dto));
    }

    /**
     * 批量复制到
     */
    @Operation(summary = "批量复制到")
    @PutMapping("/{prepare-id}/file-folder/batch-copy")
    public R<Boolean> batchCopy(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                @RequestBody List<PrepareFileFolderCopyDTO> dto) {
        return R.data(prepareFileFolderService.batchCopy(dto));
    }

    /**
     * 删除备课区文件夹
     */
    @Operation(summary = "删除备课区文件/文件夹")
    @DeleteMapping("/{prepare-id}/file-folder/{id}")
    public R<Boolean> delete(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                             @Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id) {
        return R.data(prepareFileFolderService.deleteById(id));
    }

    /**
     * 批量删除备课区文件夹
     */
    @Operation(summary = "批量删除备课区文件/文件夹")
    @DeleteMapping("/{prepare-id}/batch-delete-file-folder")
    public R<Boolean> batchDelete(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                  @Parameter(description = "备课区文件id列表", example = "[100001,100002]") @RequestBody List<Long> idList) {
        return R.data(prepareFileFolderService.batchDelete(prepareId, idList));
    }

    /**
     * 删除备课区文件夹
     */
    @Operation(summary = "下载备课区文件")
    @GetMapping("/{prepare-id}/file-folder/{id}/download")
    public R<List<CommonFileDTO>> download(@Parameter(description = "备课区id", example = "100001") @PathVariable("prepare-id") Long prepareId,
                                           @Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id) {
        return R.data(prepareFileFolderService.download(id));
    }

    /**
     * 生成分享url
     */
    @Operation(summary = "生成分享url")
    @PostMapping("/generate-share-url")
    public R<String> generateShareUrl(@RequestBody PrepareFileShareURLDto dto) {
        return R.data(prepareFileFolderService.generateShareUrl(dto), "生成成功");
    }

    /**
     * 访问别人分享的url
     */
    @Operation(summary = "访问别人分享的url")
    @PostMapping("/visit-share-content")
    public R<String> visitShareContent(@RequestBody PrepareFileShareURLDto dto) {
        return R.data(prepareFileFolderService.visitShareContent(dto), "成功");
    }

    /**
     * 保存分享的文件到备课区
     */
    @Operation(summary = "保存分享的文件到备课区")
    @PutMapping("/file-folder/{id}/save-to-prepare")
    public R<Boolean> savToPrepare(@Parameter(description = "备课区文件id", example = "100001") @PathVariable("id") Long id,
                           @RequestBody PrepareFileFolderCopyDTO dto) {
        dto.setId(id);
        return R.data(prepareFileFolderService.savToPrepare(dto));
    }

}
